package com.swt.gap.controller;

import com.swt.gap.common.PageResult;
import com.swt.gap.model.params.ElementSameForm;
import com.swt.gap.model.params.UpdateFileParam;
import com.swt.gap.model.vo.FileMetaInfo;
import com.swt.gap.model.vo.SaveFileInfoVO;
import com.swt.gap.model.vo.file.FileInfoVO;
import com.swt.gap.model.vo.UploadFileVO;
import com.swt.gap.model.vo.file.FileSameElementVO;
import com.swt.gap.service.DataResourceService;
import com.swt.gap.service.FileService;
import com.swt.gap.service.UploadService;
import com.swt.gap.util.UserLoginUtils;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.net.UnknownHostException;

import java.util.List;


@Api(tags = "201 数据资源相关")
@RestController
@RequestMapping("/file")
@Slf4j
public class FileController {

    private final UploadService uploadService;
    private final FileService fileService;
    private final DataResourceService dataResourceService;

    public FileController(UploadService uploadService, FileService fileService, DataResourceService dataResourceService) {
        this.uploadService = uploadService;
        this.fileService = fileService;
        this.dataResourceService = dataResourceService;
    }


    @PostMapping("/upload")
    @ApiOperation(value = "上传文件", notes = "上传文件")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "formData", dataType = "MultipartFile", name = "file", required = true),
            @ApiImplicitParam(paramType = "query", dataType = "int", name = "fileClassId", value = "数据类别id")
    })
    @ApiResponses({@ApiResponse(code = 201, message = "CREATED", response = UploadFileVO.class),
                   @ApiResponse(code = 406, message = "格式不支持"),
                   @ApiResponse(code = 404, message = "原始文件不存在"),
                   @ApiResponse(code = 500, message = "系统问题"),
                   @ApiResponse(code = 409, message = "已重名"),
                   @ApiResponse(code = 400, message = "文件大小为0kb,为空文件")})
    public ResponseEntity uploadFile(@RequestParam("file") MultipartFile file, @RequestParam int fileClassId) {
        //  文件存项目路径下
        UploadFileVO uploadFileVO = null;
        try {
            uploadFileVO = uploadService.uploadFile(file, fileClassId);
        } catch (IOException e) {
            e.printStackTrace();
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("系统问题，请联系管理员");
        }
        if (!uploadFileVO.getUploadSuccess()) {
            if (uploadFileVO.getFailedFile().getErrorCode().equals(1)) {
                return ResponseEntity.status(HttpStatus.NOT_ACCEPTABLE).body(uploadFileVO);
            } else if (uploadFileVO.getFailedFile().getErrorCode().equals(2)) {
                return ResponseEntity.status(HttpStatus.NOT_FOUND).body(uploadFileVO);
            } else if (uploadFileVO.getFailedFile().getErrorCode().equals(3)) {
                return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(uploadFileVO);
            } else if (uploadFileVO.getFailedFile().getErrorCode().equals(4)) {
                return ResponseEntity.status(HttpStatus.CONFLICT).body(uploadFileVO);
            } else if (uploadFileVO.getFailedFile().getErrorCode().equals(5)) {
                return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(uploadFileVO);
            }
        }
        return ResponseEntity.status(HttpStatus.CREATED).body(uploadFileVO);
    }

    @DeleteMapping("/{fileId}")
    @ApiOperation(value = "删除上传成功的数据", notes = "删除上传成功的数据")
    @ApiImplicitParam(name = "fileId", dataType = "int",paramType = "path", value = "数据id")
    @ApiResponses({@ApiResponse(code = 200, message = "ok")})
    public ResponseEntity deleteSuccessFile(@PathVariable Integer fileId){
        Integer userId = UserLoginUtils.getUserId();
        if (!dataResourceService.hasWritePermission(userId, fileId)) {
            return ResponseEntity.status(HttpStatus.FORBIDDEN).body("无操作权限");
        }
        fileService.deleteSuccessFile(fileId);
        return ResponseEntity.ok("删除成功");
    }


    @PutMapping
    @ApiOperation(value = "直接覆盖", notes = "直接覆盖")
    @ApiImplicitParams ({
            @ApiImplicitParam(name = "savedFileName", dataType = "String",paramType = "query", value = "上传保存的文件名"),
            @ApiImplicitParam(name = "fileSize", dataType = "double",paramType = "query", value = "文件大小"),
            @ApiImplicitParam(name = "oldFileId", dataType = "int",paramType = "query", value = "旧的重名数据id")
    })
    @ApiResponses({@ApiResponse(code = 200, message = "ok")})
    public ResponseEntity coverFile(@RequestParam String savedFileName, @RequestParam Double fileSize, @RequestParam Integer oldFileId){
        return ResponseEntity.ok(fileService.coverFile(savedFileName, fileSize, oldFileId));
    }

    @GetMapping("pic-video-sound")
    @ApiOperation(value = "获取图片、视频、声音的预览地址",notes = "获取图片、视频、声音的预览地址")
    @ApiImplicitParam(paramType = "query", dataType = "int", name = "fileId", value = "数据Id")
    @ApiResponse(code = 200,message = "")
    public ResponseEntity getUrl(@RequestParam Integer fileId) throws UnknownHostException {
        return ResponseEntity.ok(fileService.getUrlByFileId(fileId));
    }


    @PostMapping
    @ApiOperation(value = "重新上传", notes = "重新上传")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", dataType = "String", name = "fileName", value = "重命名之后的数据名称"),
            @ApiImplicitParam(paramType = "query", dataType = "int", name = "fileId", value = "新增的重名数据Id")
    })
    @ApiResponses({@ApiResponse(code = 201, message = "CREATED", response = UploadFileVO.class),
            @ApiResponse(code = 409, message = "已重名")})
    public ResponseEntity uploadRepeatFile(@RequestParam String fileName, @RequestParam Integer fileId) {
        UploadFileVO uploadFileVO = fileService.uploadRepeatFile(fileName, fileId);
        if(!uploadFileVO.getUploadSuccess()){
                return ResponseEntity.status(HttpStatus.CONFLICT).body(uploadFileVO);
        }
        return ResponseEntity.status(HttpStatus.CREATED).body(uploadFileVO);
    }


    @DeleteMapping
    @ApiOperation(value = "批量删除数据源", notes = "批量删除数据源")
    @ApiImplicitParam(name = "fileIds", dataType = "array",paramType = "query", value = "数据源Id集合")
    @ApiResponses({@ApiResponse(code = 200, message = "ok")})
    public ResponseEntity deleteFiles(@RequestParam List<Integer> fileIds){
        Integer userId = UserLoginUtils.getUserId();
        for (Integer fileId : fileIds) {
            if (!dataResourceService.hasWritePermission(userId, fileId)) {
                return ResponseEntity.status(HttpStatus.FORBIDDEN).body("无操作权限");
            }
        }
        fileService.deleteBatchFile(fileIds);
        return ResponseEntity.ok("删除成功");
    }


    @GetMapping("/file-info")
    @ApiOperation(value = "查看或者预览文件", notes = "查看文件")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "fileId", dataType = "Integer",paramType = "query", value = "数据源Id"),
            @ApiImplicitParam(name = "viewType", dataType = "Integer",paramType = "query", value = "查看类型 0：预览部分数据 1：查看所有数据")
    })
    @ApiResponses({@ApiResponse(code = 200, message = "ok")})
    public ResponseEntity<FileInfoVO> getFileInfo(Integer fileId,Integer viewType){
        return ResponseEntity.ok(fileService.getFileInfo(fileId,viewType));

    }
    @PostMapping("/same-elements")
    @ApiOperation(value = "同要素", notes = "同要素")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "fileId", dataType = "Integer",paramType = "query", value = "数据源Id"),
            @ApiImplicitParam(name = "elements", dataType = "ElementSameForm",paramType = "body",allowMultiple = true)
    })
    @ApiResponses({@ApiResponse(code = 200, message = "ok")})
    public ResponseEntity<PageResult<FileSameElementVO>> getFileSameElements(@RequestParam Integer fileId, @RequestParam Integer page, @RequestParam Integer size, @RequestBody List<ElementSameForm> elements){
        return ResponseEntity.ok(fileService.getFileSameElements(fileId, page ,size,elements));

    }

    @PostMapping("/save")
    @ApiOperation(value = "保存文件信息", notes = "保存文件信息")
    @ApiImplicitParams({@ApiImplicitParam(paramType = "body", dataType = "FileMetaInfo", allowMultiple = true,
            name = "fileInfos", required = true)})
    @ApiResponses({@ApiResponse(code = 201, message = "CREATED", response = Boolean.class)})
    public ResponseEntity<Boolean> saveFileInfo(@RequestBody List<FileMetaInfo> fileInfos) {
        return ResponseEntity.status(HttpStatus.CREATED).body(fileService.saveFileInfo(fileInfos));
    }

    @PostMapping("/file-info")
    @ApiOperation(value = "保存文件信息，增加密码 v2", notes = "保存文件信息，增加密码  v2")
    @ApiImplicitParams({@ApiImplicitParam(paramType = "body", dataType = "SaveFileInfoVO",
            name = "record", required = true)})
    @ApiResponses({@ApiResponse(code = 201, message = "CREATED", response = Boolean.class)})
    public ResponseEntity<Boolean> saveFileInfo2(@RequestBody SaveFileInfoVO record) {
        return ResponseEntity.status(HttpStatus.CREATED).body(fileService.saveFileInfo(record));
    }

    @PutMapping("/text-element")
    @ApiOperation(value = "新增或者编辑文件提取的要素", notes = "新增或者编辑文件提取的要素")
    @ApiImplicitParams({@ApiImplicitParam(paramType = "body", dataType = "UpdateFileParam", name = "fileInfo", required = true)})
    @ApiResponses({@ApiResponse(code = 200, message = "ok", response = String.class)})
    public ResponseEntity<String> updateFileTextElement(@RequestBody UpdateFileParam fileInfo) {
        Integer userId = UserLoginUtils.getUserId();
        if (!dataResourceService.hasWritePermission(userId, fileInfo.getFileId())) {
            return ResponseEntity.status(HttpStatus.FORBIDDEN).body("无操作权限");
        }
        return ResponseEntity.ok(fileService.updateFileTextElement(fileInfo).toString());
    }


    @GetMapping("/file-name")
    @ApiOperation(value = "判断文件名是否存在", notes = "判断文件名是否存在")
    @ApiImplicitParams(
            {@ApiImplicitParam(paramType = "query", dataType = "String", name = "fileName", required = true),
            @ApiImplicitParam(paramType = "query", dataType = "int", name = "fileClassId", required = true),
            @ApiImplicitParam(paramType = "query", dataType = "int", name = "fileType", required = true)}
    )
    @ApiResponses({@ApiResponse(code = 200, message = "ok", response = Boolean.class)})
    public ResponseEntity<Boolean> saveFileInfo(@RequestParam String fileName, @RequestParam Integer fileClassId,
            @RequestParam Integer fileType) {
        return ResponseEntity.status(HttpStatus.CREATED).body(fileService.isExistsFileName(fileName, fileClassId, fileType));
    }
}
